package com.jasmine.bjstkserver.manager.os;

import cn.hutool.core.util.StrUtil;
import com.jasmine.core.constants.enums.DictEnum;
import com.jasmine.bjstkserver.server.dict.DictService;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.region.Region;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.UUID;

/**
 * @author jasmineXz
 */
@Component
public class TxCosManager extends AbstractOsManager implements OsManager {
    private static final Logger log = LoggerFactory.getLogger(TxCosManager.class);

    private static final String SECRET_ID    = "SECRET_ID";
    private static final String SECRET_KEY   = "SECRET_KEY";
    private static final String BUCKET_NAME  = "BUCKET_NAME";
    private static final String REGION       = "REGION";
    private static final String FILE_PATH    = "FILE_PATH";
    private static final String DOMAIN       = "DOMAIN";

    @Autowired
    private DictService dictService;


    @Override
    public String put(InputStream inputStream, String fileName) {
        return null;
    }


    @Override
    public String putAsync(InputStream inputStream, String fileName, Integer userId) {
        Map<String,String> param = getParam(userId);
        COSClient cosClient = getClient(param);
        String name;
        try {
            name = param.get(FILE_PATH) + (StrUtil.isBlank(fileName) ? UUID.randomUUID().toString() + ".jpg" : fileName);
            PutObjectRequest putObjectRequest = new PutObjectRequest(
                    param.get(BUCKET_NAME),
                    name,
                    inputStream,
                    initObjectMetadata(fileName));

            cosClient.putObject(putObjectRequest).getETag();
        } finally {
            cosClient.shutdown();
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return param.get(DOMAIN) + name;
    }


    @Override
    public String put(MultipartFile file, String fileName) {
        Map<String,String> param = getParam();
        COSClient cosClient = getClient(param);
        String name = null;
        try (InputStream inputStream = file.getInputStream()){
            ObjectMetadata objectMetadata = initObjectMetadata(fileName);
            objectMetadata.setContentLength(file.getSize());

            name = param.get(FILE_PATH) + (StrUtil.isBlank(fileName) ? UUID.randomUUID().toString() + ".jpg" : fileName);
            PutObjectRequest putObjectRequest = new PutObjectRequest(
                    param.get(BUCKET_NAME),
                    name,
                    inputStream,
                    objectMetadata);
            cosClient.putObject(putObjectRequest).getETag();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            cosClient.shutdown();
        }
        return param.get(DOMAIN) + name;
    }


    @Async
    @Override
    public void deleteAsync(String fileName, Integer userId) {
        Map<String,String> param = getParam(userId);
        COSClient cosClient = getClient(param);
        String objName = StrUtil.removeAll(fileName,param.get(DOMAIN));
        try {
            cosClient.deleteObject(param.get(BUCKET_NAME), objName);
        } finally {
            cosClient.shutdown();
        }
        log.info("[BJSTK] 删除COS文件 : {}",fileName);
    }


    private COSClient getClient (Map<String,String> param) {
        COSCredentials cred = new BasicCOSCredentials(param.get(SECRET_ID), (param.get(SECRET_KEY)));
        ClientConfig clientConfig = new ClientConfig(new Region(param.get(REGION)));
        return new COSClient(cred, clientConfig);
    }


    private ObjectMetadata initObjectMetadata (String fileName) {
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentType(matchContentType(fileName));
        return objectMetadata;
    }


    private Map<String,String> getParam(){
        return dictService.getDict(DictEnum.TXYUNCOS.code());
    }


    private Map<String,String> getParam(Integer userId){
        return dictService.getDict(DictEnum.TXYUNCOS.code(),userId);
    }
}
